Skip to content

Sync Go SDK with Plugin API v3.7.0 protocol fields#11

Merged
dmortondev merged 7 commits intomainfrom
fix-missing-protocol-fields
Mar 30, 2026
Merged

Sync Go SDK with Plugin API v3.7.0 protocol fields#11
dmortondev merged 7 commits intomainfrom
fix-missing-protocol-fields

Conversation

@dmortondev
Copy link
Copy Markdown
Collaborator

Summary

Audits the Go SDK against the canonical C++ Launcher and first-party plugin implementations to close gaps between the wire protocol and what the SDK exposed. All changes match observed C++ behavior.

  • Add InitContainer type and Job.InitContainers — init containers run before the main job container when the cluster advertises supportsInitContainers. Includes Job.InstanceID (Launcher-assigned persistent identifier that plugins must round-trip unchanged), and Mount.Name (optional label for a file system mount).
  • Remove MultiCluster extension — the requestMultiClusterInfo/responseMultiClusterInfo message types (wire value 17) were removed from the protocol. The request handler and response writer method have been deleted accordingly.
  • Add memoryUsageBytes to metricsPluginMetrics.MemoryUsageBytes and MetricsResponse.memoryUsageBytes were missing. The Launcher always reads this field; zero is treated as unknown rather than a measurement of zero bytes.
  • Fix ResourceProfile serializationQueue and Constraints were missing omitempty, causing them to always serialize even when empty. C++ only sends these fields conditionally.
  • Add name and statusCode to job status stream responsesWriteJobStatus now accepts name and statusCode, matching JobStatusStream::getJobStatusJson in the C++ SDK. statusCode is forwarded from Job.StatusCode through the statusUpdate pub/sub path and omitted when empty; name is always sent (matching C++ behavior).

Breaking changes

launcher.StreamResponseWriter.WriteJobStatus has a new signature:

// Before
WriteJobStatus(id api.JobID, name, status, msg string) error

// After
WriteJobStatus(id api.JobID, name, status, statusCode, msg string) error

Plugins that implement StreamResponseWriter directly (rather than delegating to the cache helpers) must add the statusCode parameter. Pass an empty string if the scheduler does not use status codes.

Test plan

  • go test ./... passes
  • go test -race ./... passes
  • Verify Job.InitContainers, Job.InstanceID, and Mount.Name round-trip correctly through Job.WithFields
  • Verify memoryUsageBytes appears in metrics JSON output with a non-zero value
  • Verify statusCode is omitted from stream responses when empty, present when set

Two fields present in the C++ Job type were absent from the Go SDK:

- InitContainer type and initContainers on Job, so plugins can receive
  and process init container specs from job submissions.
- InstanceID on Job, preserving the Launcher instance identifier used
  in load-balanced deployments.

Also add supportsInitContainers to the ClusterInfo response so plugins
can advertise init container capability to the Launcher.
The MultiCluster extension (message type 17, MultiClusterPlugin,
MultiClusterResponseWriter, WriteClusters, ClusterInfo.Name) was a
prototype that went in a different direction and is not part of the
Launcher Plugin API. Remove it entirely.
The C++ Launcher reads memoryUsageBytes from the MetricsResponse but the
Go SDK never populated it, so Go plugins always reported zero for memory
usage. Add MemoryUsageBytes to PluginMetrics so plugins can report current
process memory, and wire it through to the MetricsResponse payload.
The C++ Mount struct has an optional name field that is serialized when
non-empty, but Go's Mount had no equivalent. Add Name string with
omitempty to match the C++ wire format.
Queue and Constraints lacked omitempty, causing Go to always emit
"queue": "" and "placementConstraints": null even for profiles with
neither. C++ only sends these fields when non-empty.
JobStatusStreamResponse has always had a "name" field, but
NewJobStatusStreamResponse never populated it — the field was silently
zero-valued on every status update. C++ plugins always send the job name
(from the full Job object via JobStatusStream::getJobStatusJson), and the
Launcher passes it through to Workbench in the raw JSON.

Add a name parameter to WriteJobStatus, thread it through the protocol
constructor, and update the cache to supply job.Name from the stored job.
Also adds Name to the internal statusUpdate struct and to plugintest's
StatusUpdate so tests can assert on it.
Wire Job.StatusCode through the status streaming path so plugins can
forward cluster-specific status codes (e.g. Kubernetes pod phase) to
the Launcher, matching C++ plugin behavior.
@dmortondev dmortondev force-pushed the fix-missing-protocol-fields branch from 479a7c0 to 4ed02ba Compare March 24, 2026 17:19
@dmortondev dmortondev merged commit 9719291 into main Mar 30, 2026
11 checks passed
@dmortondev dmortondev deleted the fix-missing-protocol-fields branch March 30, 2026 19:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant